package drds.configuration.db.xml_mapping.sql_execute.primary_key_generator;


import drds.configuration.db.xml_mapping.configuration.Configuration;
import drds.configuration.db.xml_mapping.sql_execute.Mapper;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class AutoSetModePrimaryKeyGenerator implements PrimaryKeyGenerator {
    public static final AutoSetModePrimaryKeyGenerator INSTANCE = new AutoSetModePrimaryKeyGenerator();

    @Override
    public void insert(Mapper mapper, Statement statement, Object parameter) {
        final String primaryKeyAlias = mapper.getPrimaryKeyAlias();
        final String primaryKeyPropertyName = mapper.getPrimaryKeyPropertyName();
        final String primaryKeyColumnName = mapper.getPrimaryKeyColumnName();
        if (primaryKeyPropertyName == null || primaryKeyColumnName == null) {
            return;
        }
        //
        try (ResultSet resultSet = statement.getGeneratedKeys()) {
            final ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
            final Configuration configuration = mapper.getConfiguration();
            assignPrimaryKey(configuration, parameter, primaryKeyAlias, primaryKeyPropertyName, primaryKeyColumnName, resultSet, resultSetMetaData);
        } catch (Exception e) {
            throw new RuntimeException("Error getting generated key or setting result to parameter_handler object. Cause: " + e, e);
        }
    }

    private void assignPrimaryKey(Configuration configuration, Object parameter, String primaryKeyAlias, String primaryKeyPropertyName, String primaryKeyColumnName, ResultSet resultSet, ResultSetMetaData resultSetMetaData) throws SQLException {
        boolean object = false;
        boolean map = false;
        if (parameter instanceof HashMap) {
            map = true;
        } else {
            object = true;
        }
        if (map) {
            //map
            resultSet.next();
            assignPrimaryKeysOfMap((HashMap<String, Object>) parameter, primaryKeyAlias, primaryKeyPropertyName, primaryKeyColumnName, resultSet);
        } else if (object) {
            // object
            resultSet.next();
            assignPrimaryKeysOfObject(configuration, parameter, primaryKeyAlias, primaryKeyPropertyName, primaryKeyColumnName, resultSet, resultSetMetaData);
        } else {
            throw new IllegalArgumentException("");
        }
    }


    private void assignPrimaryKeysOfMap(HashMap<String, Object> map, String primaryKeyAlias, String primaryKeyPropertyName, String primaryKeyColumnName, ResultSet resultSet) throws SQLException {
        if (map == null) {
            return;
        }
        //前面已经进行resultSet.next();处理
        long object = resultSet.getLong(1);
        if (primaryKeyAlias != null) {
            map.putIfAbsent(primaryKeyAlias, new HashMap<String, Object>());
            HashMap<String, Object> hashMap = (HashMap<String, Object>) map.get(primaryKeyAlias);
            hashMap.put(primaryKeyColumnName, object);
        } else {
            map.put(primaryKeyColumnName, object);
        }

    }

    private void assignPrimaryKeysOfObject(Configuration configuration, Object parameter, String primaryKeyAlias, String primaryKeyPropertyName, String primaryKeyColumnName, ResultSet resultSet, ResultSetMetaData resultSetMetaData) throws SQLException {
        //前面已经进行resultSet.next();处理
        Object object = resultSet.getObject(primaryKeyColumnName);
        //只会是map
    }

    //
    public void batchInsert(Mapper mapper, Statement statement, List<Map<String, Object>> mapList) {
        final String primaryKeyColumnName = mapper.getPrimaryKeyColumnName();
        //
        try (ResultSet resultSet = statement.getGeneratedKeys()) {
            assignPrimaryKeysOfMapList(mapList, primaryKeyColumnName, resultSet);
        } catch (Exception e) {
            throw new RuntimeException("Error getting generated key or setting result to parameter_handler object. Cause: " + e, e);
        }
    }

    private void assignPrimaryKeysOfMapList(List<Map<String, Object>> mapList, String primaryKeyColumnName, ResultSet resultSet) throws SQLException {
        int count = 0;
        while (resultSet.next()) {
            assignPrimaryKeysOfMap((HashMap<String, Object>) mapList.get(count++), primaryKeyColumnName, resultSet);
        }
    }

    private void assignPrimaryKeysOfMap(HashMap<String, Object> map, String primaryKeyColumnName, ResultSet resultSet) throws SQLException {
        if (map == null) {
            return;
        }
        //前面已经进行resultSet.next();处理
        long object = resultSet.getLong(1);
        map.put(primaryKeyColumnName, object);
    }

}
